package com.tony.mulitithread.controller;

import com.tony.mulitithread.domain.FileInfo;
import com.tony.mulitithread.domain.ResultBean;
import com.tony.mulitithread.service.FileService;
import com.tony.mulitithread.utils.*;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author yimeng
 * @Date 2023/12/19 23:29
 * @PackageName:com.tony.mulitithread.controller
 * @ClassName: FileQueryController2
 * @Description: TODO
 * @Version 1.0
 */
@RestController
@RequestMapping("/fileQuery2")
public class FileQueryController2 {
    @Resource
    private FileService fileService;


    //单线程查询单表
    @GetMapping("/single")
    public ResultBean<List<FileInfo>> queryList() {
        return new ResultBean<>(fileService.queryFiles());
    }

    //up主2法1，多线程查单表
    @GetMapping("/muliti1")
    public ResultBean<List<FileInfo>> queryFilesByMulitiThread() throws Exception {
        long l = System.currentTimeMillis();
        int totalNum = fileService.countNum();
        //重写多线程中引用的方法。这个写法或者lambda表达式的写法都行。
//        List<T> threadHandle = ThreadPoolUtils.threadPool(totalNum, new ThreadTableDataQuery() {
//            @Override
//            public List<T> selectTableData(Integer page, Integer limit) throws Exception {
//                return fileService.selectTableData(page, limit);
//            }
//        });
        //lambda表达式写法
        List<T> threadHandle = ThreadPoolUtils.threadPool(totalNum, (page, limit) -> fileService.selectTableData(page, limit));

        //转换为list对象.下面这个方法是用alibaba的反射方法转为具体对象的，但是测试发现效果比较慢，不如反射。
//        List<FileInfo> fileInfos= JSON.parseArray(JSON.toJSONString(threadHandle), FileInfo.class);
        //所以建议使用下面这个：
        List<FileInfo> fileInfos = JsonUtils.toList(threadHandle, FileInfo.class);
        System.out.println("总数：" + fileInfos.size());
        System.out.println("第一条：" + fileInfos.get(0));
        System.out.println("最后一条：" + fileInfos.get(fileInfos.size() - 1));
        System.out.println("方法1耗时：" + (System.currentTimeMillis() - l));
        return new ResultBean<>(fileInfos);
    }

    //up主2法2，多线程查单表
    @GetMapping("/muliti2")
    public ResultBean<List<FileInfo>> queryFilesByMulitiThread2() throws Exception {
        long l = System.currentTimeMillis();
        int totalNum = fileService.countNum();
        //重写多线程中引用的方法
//        List<T> threadAsync = ThreadPoolUtils2.threadAsync(totalNum, new ThreadAsyncTableDataQuery() {
//            @Override
//            public Future<List<T>> selectTableDataAsync(Integer page, Integer limit) throws Exception {
//                return fileService.selectTableDataAsync(page, limit);
//            }
//        });
        //lambda表达式写法
        List<T> threadAsync = ThreadPoolUtils2.threadAsync(totalNum, (page, limit) -> fileService.selectTableDataAsync(page, limit));
        //转换为list对象
        List<FileInfo> fileInfos = JsonUtils.toList(threadAsync, FileInfo.class);
        System.out.println("总数：" + fileInfos.size());
        System.out.println("第一条：" + fileInfos.get(0));
        System.out.println("最后一条：" + fileInfos.get(fileInfos.size() - 1));
        System.out.println("方法2耗时：" + (System.currentTimeMillis() - l));
        return new ResultBean<>(fileInfos);
    }
}
